﻿#include "QNetworkTrafficMonitor.h"
#include <QDebug>
#include <QNetworkInterface>
#include <QFile>
#include <QTextStream>
#include <QMap>
#include <memory>

#ifdef Q_OS_WIN
#include <windows.h>
#include <iphlpapi.h>
#pragma comment(lib, "iphlpapi.lib")
#endif

QNetworkTrafficMonitor::QNetworkTrafficMonitor() {
    m_timer.start();
    // 首次获取原始数据
    m_prevTraffics = getInterfaceTrafficsImpl();
    // 初始化累计值
    for (auto& traffic : m_prevTraffics) {
        traffic.prevReceived = traffic.rawReceived;
        traffic.prevSent = traffic.rawSent;
        traffic.bytesReceived = traffic.prevReceived;
        traffic.bytesSent = traffic.prevSent;
        // 初始化上一次速率计算用的累计值
        traffic.lastRateReceived = traffic.prevReceived;
        traffic.lastRateSent = traffic.prevSent;
    }
}

QVector<NetworkInterfaceTraffic> QNetworkTrafficMonitor::getInterfaceTraffics() {
    QVector<NetworkInterfaceTraffic> current = getInterfaceTrafficsImpl();

    // 构建上一次数据的映射
    QMap<QString, NetworkInterfaceTraffic> prevMap;
    for (const auto& t : m_prevTraffics) {
        prevMap[t.name] = t;
    }

    // 1. 先更新累计值（基于原始值计算）
    for (auto& curr : current) {
        if (prevMap.contains(curr.name)) {
            const auto& prev = prevMap[curr.name];
            quint64 rxDelta, txDelta;

            // 计算原始值差值（处理溢出）
            if (curr.rawReceived >= prev.rawReceived) {
                rxDelta = curr.rawReceived - prev.rawReceived;
            } else {
                rxDelta = (0xFFFFFFFFULL - prev.rawReceived) + curr.rawReceived + 1;
            }

            if (curr.rawSent >= prev.rawSent) {
                txDelta = curr.rawSent - prev.rawSent;
            } else {
                txDelta = (0xFFFFFFFFULL - prev.rawSent) + curr.rawSent + 1;
            }

            // 更新累计值
            curr.prevReceived = prev.prevReceived + rxDelta;
            curr.prevSent = prev.prevSent + txDelta;
            // 继承上一次速率计算用的累计值
            curr.lastRateReceived = prev.lastRateReceived;
            curr.lastRateSent = prev.lastRateSent;
        } else {
            // 新接口初始化
            curr.prevReceived = curr.rawReceived;
            curr.prevSent = curr.rawSent;
            // 首次出现，速率计算基准值设为当前累计值
            curr.lastRateReceived = curr.prevReceived;
            curr.lastRateSent = curr.prevSent;
        }

        // 更新显示值
        curr.bytesReceived = curr.prevReceived;
        curr.bytesSent = curr.prevSent;
    }

    // 2. 基于更新后的累计值计算速率（关键时序修复）
    calculateRates(current);

    // 3. 保存当前累计值作为下一次速率计算的基准
    for (auto& curr : current) {
        curr.lastRateReceived = curr.prevReceived;
        curr.lastRateSent = curr.prevSent;
    }

    m_prevTraffics = current;
    return current;
}

// 修正速率计算：使用专门记录的速率基准值
void QNetworkTrafficMonitor::calculateRates(QVector<NetworkInterfaceTraffic>& current) {
    qint64 timeDiff = 0;
    if (!current.isEmpty() && !m_prevTraffics.isEmpty()) {
        timeDiff = current.first().lastUpdateTime - m_prevTraffics.first().lastUpdateTime;
    }
    double timeSec = timeDiff > 0 ? timeDiff / 1000.0 : 1.0;

    for (auto& curr : current) {
        // 计算累计值差值（使用专门的速率基准值）
        quint64 rxDelta = curr.prevReceived - curr.lastRateReceived;
        quint64 txDelta = curr.prevSent - curr.lastRateSent;

        // 过滤异常值（避免瞬间波动）
        if (rxDelta > 0x10000000ULL) { // 单次差值超过256MB视为异常
            rxDelta = 0;
        }
        if (txDelta > 0x10000000ULL) {
            txDelta = 0;
        }

        // 计算速率（确保时间差合理）
        if (timeSec > 0.1) { // 至少0.1秒的间隔才计算速率，避免短时间误差
            curr.downloadRate = rxDelta / timeSec;
            curr.uploadRate = txDelta / timeSec;
        } else {
            // 时间过短，沿用上次速率
            if (!m_prevTraffics.isEmpty()) {
                QMap<QString, NetworkInterfaceTraffic> prevMap;
                for (const auto& t : m_prevTraffics) {
                    prevMap[t.name] = t;
                }
                if (prevMap.contains(curr.name)) {
                    curr.downloadRate = prevMap[curr.name].downloadRate;
                    curr.uploadRate = prevMap[curr.name].uploadRate;
                } else {
                    curr.downloadRate = 0;
                    curr.uploadRate = 0;
                }
            } else {
                curr.downloadRate = 0;
                curr.uploadRate = 0;
            }
        }
    }
}

// 以下函数保持不变，仅确保rawReceived和rawSent正确赋值
TotalNetworkTraffic QNetworkTrafficMonitor::getTotalTraffic() {
    TotalNetworkTraffic total{};
    auto traffics = getInterfaceTraffics();

    for (const auto& iface : traffics) {
        total.totalBytesReceived += iface.bytesReceived;
        total.totalBytesSent += iface.bytesSent;
        total.totalDownloadRate += iface.downloadRate;
        total.totalUploadRate += iface.uploadRate;
    }

    return total;
}

#ifdef Q_OS_WIN
QVector<NetworkInterfaceTraffic> QNetworkTrafficMonitor::getInterfaceTrafficsImpl() {
    QVector<NetworkInterfaceTraffic> result;
    DWORD bufferSize = 0;

    QList<QNetworkInterface> qtInterfaces = QNetworkInterface::allInterfaces();
    if (qtInterfaces.isEmpty()) {
        qWarning() << "Qt接口列表为空";
        return result;
    }

    if (GetIfTable(nullptr, &bufferSize, FALSE) != ERROR_INSUFFICIENT_BUFFER) {
        qWarning() << "获取缓冲区大小失败";
        return result;
    }

    std::unique_ptr<BYTE[]> buffer(new BYTE[bufferSize + 1024]);
    PMIB_IFTABLE ifTable = reinterpret_cast<PMIB_IFTABLE>(buffer.get());

    if (GetIfTable(ifTable, &bufferSize, FALSE) != NO_ERROR) {
        qWarning() << "获取接口表失败";
        return result;
    }

    for (DWORD i = 0; i < ifTable->dwNumEntries; ++i) {
        const MIB_IFROW& ifRow = ifTable->table[i];
        NetworkInterfaceTraffic traffic;

        bool found = false;
        foreach (const QNetworkInterface& qtIface, qtInterfaces) {
            if (qtIface.index() == static_cast<int>(ifRow.dwIndex)) {
                if (qtIface.flags() & QNetworkInterface::IsLoopBack) {
                    break;
                }
                traffic.name = qtIface.name();
                traffic.description = qtIface.humanReadableName();
                traffic.macAddress = qtIface.hardwareAddress();
                traffic.isUp = qtIface.flags() & QNetworkInterface::IsUp;
                found = true;
                break;
            }
        }
        if (!found) continue;

        // 存储32位原始值
        traffic.rawReceived = static_cast<quint32>(ifRow.dwInOctets);
        traffic.rawSent = static_cast<quint32>(ifRow.dwOutOctets);
        traffic.packetsReceived = static_cast<quint64>(ifRow.dwInUcastPkts) + ifRow.dwInNUcastPkts;
        traffic.packetsSent = static_cast<quint64>(ifRow.dwOutUcastPkts) + ifRow.dwOutNUcastPkts;
        traffic.lastUpdateTime = m_timer.elapsed();

        result.append(traffic);
    }

    return result;
}
#else
QVector<NetworkInterfaceTraffic> QNetworkTrafficMonitor::getInterfaceTrafficsImpl() {
    QVector<NetworkInterfaceTraffic> result;

    QList<QNetworkInterface> qtInterfaces = QNetworkInterface::allInterfaces();
    if (qtInterfaces.isEmpty()) {
        qWarning() << "Qt接口列表为空";
        return result;
    }

    QFile devFile("/proc/net/dev");
    if (!devFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
        qWarning() << "无法打开/proc/net/dev:" << devFile.errorString();
        return result;
    }

    QTextStream in(&devFile);
    in.readLine();
    in.readLine();

    QString line;
    while (in.readLineInto(&line)) {
        line = line.trimmed();
        int colonIndex = line.indexOf(':');
        if (colonIndex == -1) continue;

        QString ifaceName = line.left(colonIndex).trimmed();
        NetworkInterfaceTraffic traffic;

        bool found = false;
        foreach (const QNetworkInterface& qtIface, qtInterfaces) {
            if (qtIface.name() == ifaceName) {
                if (qtIface.flags() & QNetworkInterface::IsLoopBack) {
                    break;
                }
                traffic.name = qtIface.name();
                traffic.description = qtIface.humanReadableName();
                traffic.macAddress = qtIface.hardwareAddress();
                traffic.isUp = qtIface.flags() & QNetworkInterface::IsUp;
                found = true;
                break;
            }
        }
        if (!found) continue;

        QStringList stats = line.mid(colonIndex + 1).split(QRegExp("\\s+"), Qt::SkipEmptyParts);
        if (stats.size() >= 10) {
            // 存储32位原始值
            traffic.rawReceived = static_cast<quint32>(stats[0].toULongLong());
            traffic.rawSent = static_cast<quint32>(stats[8].toULongLong());
            traffic.packetsReceived = stats[1].toULongLong();
            traffic.packetsSent = stats[9].toULongLong();
        }

        traffic.lastUpdateTime = m_timer.elapsed();
        result.append(traffic);
    }

    devFile.close();
    return result;
}
#endif
